//////////////////////////////////////////////////////////////////////
//
//  CryEngine Source code
//	
//	File:CVars.cpp
//  Implementation of CVars class
//
//	History:
//	September 23, 2004: Created by Ivo Herzeg <ivo@crytek.de>
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"

//need global var as the singleton approach is too expensive
Console g_Consoleself;
namespace 
{
	int g_ConsoleInstanceCount;
}

Console::Console()
{
	if(g_ConsoleInstanceCount++)
		abort();
}

static void CADebugText(IConsoleCmdArgs *pArgs)
{
#ifndef CONSOLE_CONST_CVAR_MODE
	if(pArgs->GetArgCount() == 1)
	{
		CryLogAlways("%d", Console::GetInst().ca_DebugText);
	}
	else if(pArgs->GetArgCount() >= 2)
	{
		if(strcmp(pArgs->GetArg(1), "0") == 0)
		{
			Console::GetInst().ca_DebugText = 0;
			Console::GetInst().ca_DebugTextTarget = "";
			Console::GetInst().ca_DebugTextLayer = 0xffffffff;
		}
		else if(atoi(pArgs->GetArg(1)) > 0)
		{
			Console::GetInst().ca_DebugText = 1;
			Console::GetInst().ca_DebugTextTarget = "";
			Console::GetInst().ca_DebugTextLayer = 0xffffffff;
		}
		else
		{
			Console::GetInst().ca_DebugText = 1;
			Console::GetInst().ca_DebugTextTarget = pArgs->GetArg(1);
			Console::GetInst().ca_DebugTextLayer = 0xffffffff;
		}

		if(pArgs->GetArgCount() > 2)
		{
			Console::GetInst().ca_DebugTextLayer = atoi(pArgs->GetArg(2));
		}
	}
#endif
}

void Console::Init()
{
	ca_CharEditModel="objects/characters/sdk_player/sdk_player.cdf";
	REGISTER_STRING( "ca_CharEditModel", ca_CharEditModel,	VF_NULL, CVARHELP("") );
  assert(this);
	DefineConstIntCVar(ca_DrawVEGInfo,0,	VF_CHEAT,	"if set to 1, the VEG debug info is drawn"	);
	DefineConstIntCVar(ca_DrawBBox,0,	VF_CHEAT,	"if set to 1, the own bounding box of the character is drawn"	);
	DefineConstIntCVar(ca_DrawSkeleton, 0,	VF_CHEAT,	"if set to 1, the skeleton is drawn" );
	DefineConstIntCVar(ca_DrawDecalsBBoxes, 0,	VF_CHEAT,	"if set to 1, the decals bboxes are drawn"	);
	DefineConstIntCVar(ca_DrawPositionPre,	0,	VF_CHEAT,"draws the world position of the character (before update)");
	DefineConstIntCVar(ca_DrawPositionPost,	0,	VF_CHEAT, "draws the world position of the character (after update)");
	DefineConstIntCVar(ca_DrawEmptyAttachments, 0,	VF_CHEAT, "draws a wireframe cube if there is no object linked to an attachment");
	DefineConstIntCVar(ca_DrawWireframe, 0,	VF_CHEAT, "draws a wireframe on top of the rendered character");
	DefineConstIntCVar(ca_DrawAimPoses, 0,	VF_CHEAT, "draws the wireframe of the aim poses");
	DefineConstIntCVar(ca_DrawLookIK, 0, VF_CHEAT, "draws a visualization of look ik");
	DefineConstIntCVar(ca_DrawTangents, 0,	VF_CHEAT, "draws the tangents of the rendered character");
	DefineConstIntCVar(ca_DrawBinormals, 0,	VF_CHEAT, "draws the binormals of the rendered character");
	DefineConstIntCVar(ca_DrawNormals, 0,	VF_CHEAT,"draws the normals of the rendered character");
	DefineConstIntCVar(ca_DrawAttachments, 1,	VF_CHEAT, "if this is 0, will not draw the attachments objects");
	DefineConstIntCVar(ca_DrawFaceAttachments, 1,	0, "if this is 0, will not draw the skin attachments objects");
	DefineConstIntCVar(ca_DrawAttachmentOBB, 0,	VF_CHEAT, "if this is 0, will not draw the attachments objects"	);
	DefineConstIntCVar(ca_DrawBaseMesh, 1,	VF_CHEAT, "if this is 0, will not draw the characters");
	DefineConstIntCVar(ca_DrawLocator, 0,	0,	"if this is 1, we will draw the body and move-direction. If this is 2, we will also print out the move direction" );
	DefineConstIntCVar(ca_DrawIdle2MoveDir, 0,	0,	"if this is 1, we will draw the initial Idle2Move dir" );
	DefineConstIntCVar(ca_DrawFootPlants, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, it will print some debug boxes at the feet of the character"	);
	DefineConstIntCVar(ca_DrawCGA, 1,	VF_CHEAT, "if this is 0, will not draw the CGA characters");
	DefineConstIntCVar(ca_DrawCHR, 1,	VF_CHEAT, "if this is 0, will not draw the CHR characters");
	DefineConstIntCVar(ca_DrawCC, 1,	VF_CHEAT, "if this is 0, will not draw the CC characters");
	DefineConstIntCVar(ca_DrawCGAAsSkin, 0,	0, "if this is 1, will draw the CGA characters using skin (dp calls decreased)");
	DefineConstIntCVar(ca_DebugAnimMemTracking, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, then its shows the anim-key allocations" );
	REGISTER_COMMAND("ca_DebugText", (ConsoleCommandFunc)CADebugText, VF_CHEAT|VF_DUMPTODISK, "if this is 1, it will print some debug text on the screen\nif you give a file path or part of it instead, only the info for that character will appear");
	ca_DebugTextLayer = 0xffffffff;
	DefineConstIntCVar(ca_DebugCommandBuffer, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, it will print the amount of commands for the blend-buffer" );
	DefineConstIntCVar(ca_DebugSubstateTransitions, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, it will be possible to test blending between sub-states of an AAC" );
	DefineConstIntCVar(ca_PrintDesiredSpeed, 0,	VF_CHEAT|VF_DUMPTODISK, "if this is 1, it will print the desired speed of the human characters"	);
	DefineConstIntCVar(ca_DebugFootPlants, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, it will print some debug text on the screen"	);
	DefineConstIntCVar(ca_FootAnchoring, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, it will print some debug boxes at the feet of the character"	);
	DefineConstIntCVar(ca_GroundAlignment, 1,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, the legs of human characters will align with the terrain"	);
	DefineConstIntCVar(ca_DebugAnimationStreaming, 0,	VF_CHEAT|VF_DUMPTODISK,	"if this is 1, then it shows what animations are streamed in" );
	DefineConstIntCVar(ca_SmoothStrafe,	1, VF_CHEAT,"If this is 1, then we smooth the strafe vector");
	DefineConstIntCVar(ca_LoadUncompressedChunks,	0, VF_CHEAT, "If this 1, then uncompressed chunks prefer compressed while loading");
	DefineConstIntCVar(ca_NoDeform, 0,	VF_CHEAT,	"the skinning is not performed during rendering if this is 1");
	DefineConstIntCVar(ca_UseMorph, 1,	VF_CHEAT,	"the morph skinning step is skipped (it's part of overall skinning during rendering)");



	DefineConstIntCVar(ca_NoAnim, 0,	VF_CHEAT,	"the animation isn't updated (the characters remain in the same pose)");
	DefineConstIntCVar(ca_UsePhysics, 1,	VF_CHEAT, "the physics is not applied (effectively, no IK)");
	DefineConstIntCVar(ca_UseLookIK, 1,	VF_CHEAT,	"If this is set to 1, then we are adding a look-at animation to the skeleton"	);
	DefineConstIntCVar(ca_UseAimIK,        1,	VF_CHEAT, "If this is set to 1, then we are adding a look-at animation to the skeleton");
	DefineConstIntCVar(ca_UseAimIKRefPose, 0, VF_CHEAT, 	"If this is set to 1, adjust aim pose by the reference pose if present" );
	DefineConstIntCVar(ca_DrawAimIKVEGrid, 0,	VF_CHEAT,	"if set to 1, we will the the grid with the virtual examples"	);
	DefineConstIntCVar(ca_UseFacialAnimation, 1,	VF_CHEAT,	
		"If this is set to 1, we can play facial animations");
	DefineConstIntCVar(ca_RandomScaling, 0,	VF_CHEAT, 
		"If this is set to 1, then we apply ransom scaling to characters");
	DefineConstIntCVar(ca_LockFeetWithIK, 1,	VF_CHEAT, 
		"If this is set to 1, then we lock the feet to prevent sliding when additive animations are used" 
		);
	DefineConstIntCVar(ca_UseAllJoints, 1,	VF_CHEAT, 
		"if set to 1, then have no Animation-LOD (debugging feature for animation LOD)");
	DefineConstIntCVar(ca_ForceUpdateSkeletons, 0, VF_CHEAT, "Always update all skeletons, even if not visible.");
	DefineConstIntCVar(ca_ApplyJointVelocitiesMode, 2, VF_CHEAT, "Joint velocity preservation code mode: 0=Disabled, 1=Physics-driven, 2=Animation-driven");
	DefineConstIntCVar(ca_UseDecals, 0,	0,	"if set to 0, effectively disables creation of decals on characters\n2 - alternative method of calculating/building the decals" );
	DefineConstIntCVar(ca_DebugModelCache,  0,	VF_CHEAT,	"shows what models are currently loaded and how much memory they take");
	DefineConstIntCVar(ca_DebugAnimUpdates, 0,	VF_CHEAT,	"shows the amount of skeleton-updates" );
	DefineConstIntCVar(ca_DebugAnimUsage,   0,	VF_CHEAT,	"shows what animation assets are used in the level" );
	DefineConstIntCVar(ca_DebugAnimUsageOnFileAccess,   0,	VF_CHEAT,	"shows what animation assets are used in the level, triggered by key fileAccess events" );
	DefineConstIntCVar(ca_StoreAnimNamesOnLoad,   0,	VF_CHEAT,	"stores the names of animations during load to allow name lookup for debugging" );
	DefineConstIntCVar(ca_DumpUsedAnims,    0,	VF_CHEAT,	"writes animation asset statistics to the disk" );
	DefineConstIntCVar(ca_AnimWarningLevel, 3,	VF_CHEAT|VF_DUMPTODISK, 
		"if you set this to 0, there won't be any\nfrequest warnings from the animation system");
	DefineConstIntCVar(ca_KeepModels, 0,	VF_CHEAT, 
		"If set to 1, will prevent models from unloading from memory\nupon destruction of the last referencing character");
	// if this is not empty string, the animations of characters with the given model will be logged
	DefineConstIntCVar(ca_DebugSkeletonEffects, 0,	VF_CHEAT, "If true, dump log messages when skeleton effects are handled." );
	DefineConstIntCVar(ca_lipsync_phoneme_offset, 20,	VF_CHEAT, "Offset phoneme start time by this value in milliseconds" );
	DefineConstIntCVar(ca_lipsync_phoneme_crossfade, 70,	VF_CHEAT, "Cross fade time between phonemes in milliseconds" );
	DefineConstIntCVar(ca_eyes_procedural, 1, 0, "Enables/Disables procedural eyes animation" );
	DefineConstIntCVar(ca_lipsync_debug, 0,	VF_CHEAT,	"Enables facial animation debug draw" );
	DefineConstIntCVar(ca_DebugFacial, 0,	VF_CHEAT,	"Debug facial playback info"	);
	DefineConstIntCVar(ca_DebugFacialEyes, 0, VF_CHEAT, "Debug facial eyes info" );
	DefineConstIntCVar(ca_SkipLoadThinFat, SKIPLOADTHINFAT_START_VAL, VF_CHEAT, "Skip loading fat\thin stuff if enabled");
	DefineConstIntCVar(ca_DebugADIKTargets, 0,	VF_CHEAT,	"If 1, then it will show if there are animation-driven IK-Targets for this model." );
	DefineConstIntCVar(ca_DebugCaps, 0,	0,	"Display current blended motion capabilities." );
	DefineConstIntCVar(ca_SaveAABB, 0,	0,	"if the AABB is invalid, replace it by the default AABB" );
	DefineConstIntCVar(ca_FPWeaponInCamSpace, 1,	0,	"if this is 1, then we attach the weapon to the camera" );
	DefineConstIntCVar(ca_DebugCriticalErrors, 0,	VF_CHEAT,	"if 1, then we stop with a Fatal-Error if we detect a serious issue");
	DefineConstIntCVar(ca_UseIMG_CAF, 1,	VF_CHEAT,	"if 1, then we use the IMG file. In development mode it is suppose to be off");
	DefineConstIntCVar(ca_UseIMG_AIM, 1,	VF_CHEAT,	"if 1, then we use the IMG file. In development mode it is suppose to be off");
	DefineConstIntCVar(ca_UnloadAnimationCAF, 1,	VF_DUMPTODISK,	"unloading streamed CAFs as soon as they are not used" );
	DefineConstIntCVar(ca_UnloadAnimationDBA, 1,	VF_NULL,	"if 1, then unload DBA if not used");
	DefineConstIntCVar(ca_UseAnimationsCache, 0,	VF_DUMPTODISK,	"use dynamically unpacked animations cache" );
	DefineConstIntCVar(ca_fullAnimStatistics, 0, 0, "If 1, animation statistics shows all animations LMG is consist of, but does not show LMG names themselves.\n" \
		"If 0, shows only top-level LMG names" );
	DefineConstIntCVar(ca_EnableAssetStrafing, 1,	0,	"asset strafing is disabled by default" );
	DefineConstIntCVar(ca_EnableAssetTurning, 1,	0,	"asset tuning is disabled by default" );
	DefineConstIntCVar(ca_AMC, 1,	0,	"enable some AMC functionality" );
	DefineConstIntCVar(ca_AMC_SmoothTurn,	1, VF_CHEAT,"If this is 1, then we smooth the turn speed");
	DefineConstIntCVar(ca_AnimActionDebug, 0, VF_CHEAT,	"Enables debugging information for the AnimActions" );
	DefineConstIntCVar(ca_cloth_vars_reset, 2,	0,	"1 - load the values from the next char, 1 - apply normally, 2+ - ignore" );
	DefineConstIntCVar(ca_SerializeSkeletonAnim, 0, VF_CHEAT, "Turn on CSkeletonAnim Serialization.");
#if USE_FACIAL_ANIMATION_FRAMERATE_LIMITING
	DefineConstIntCVar(ca_FacialAnimationFramerate, 20, VF_CHEAT, "Update facial system at a maximum framerate of n. This framerate falls off linearly to zero with the distance.");
#endif
	DefineConstIntCVar(ca_AllowMultipleEffectsOfSameName, 1, VF_CHEAT, "Allow a skeleton animation to spawn more than one instance of an effect with the same name on the same instance.");
	DefineConstIntCVar(ca_UseAssetDefinedLod, 0, VF_CHEAT, "Lowers render LODs for characters with respect to \"consoles_lod0\" UDP. Requires characters to be reloaded.");
	DefineConstIntCVar(ca_Validate, 0,	VF_CHEAT,	"if set to 1, will run validation on animation data"	);

	// Command Buffer
	DefineConstIntCVar(ca_UseJointMasking, 1,	VF_DUMPTODISK,	"Use Joint Masking to speed up motion decoding.");

	// Multi-Threading
	DefineConstIntCVar(ca_disable_thread, 1, VF_DUMPTODISK, "TEMP Disable Animation Thread.");
	DefineConstIntCVar(ca_thread, 1, VF_DUMPTODISK, "If >0 enables Animation Multi-Threading.");
	DefineConstIntCVar(ca_thread0Affinity, 5, VF_DUMPTODISK, "Affinity of first Animation Thread.");
	DefineConstIntCVar(ca_thread1Affinity, 3, VF_DUMPTODISK, "Affinity of second Animation Thread.");

	// Animation data caching behavior (PC specific)
	DefineConstIntCVar(ca_PrecacheAnimationSets, 0, VF_NULL, "Enable Precaching of Animation Sets per Character.");
	DefineConstIntCVar(ca_DisableAnimationUnloading, 0, VF_NULL, "Disable Animation Unloading.");

	// vars in console .cfgs
	REGISTER_CVAR(ca_physicsProcessImpact, 0, VF_CHEAT|VF_DUMPTODISK, "Process physics impact pulses.");
	REGISTER_CVAR(ca_MemoryUsageLog, 0,	VF_CHEAT, "enables a memory usage log" );

	REGISTER_CVAR(ca_ParametricPoolSize, 64,	0, "Size of the parametric pool" );

	// cvars used in the game
	REGISTER_CVAR(ca_GameControlledStrafing, 1, VF_CHEAT,	"Use game controlled strafing/curving flag, instead of low level calculated curving weight." );
	DefineConstIntCVar(ca_UseOldStrafeSmoothing, 1, VF_CHEAT, "Use old smoothing code to calculate the travel angle and strafe blendspace parameters.");


	REGISTER_CVAR(ca_DecalSizeMultiplier, 1.0f,	VF_CHEAT,"The multiplier for the decal sizes"	);
	REGISTER_CVAR(ca_DeathBlendTime, 0.3f,	VF_CHEAT, "Specifies the blending time between low-detail dead body skeleton and current skeleton" );
	REGISTER_CVAR(ca_lipsync_vertex_drag, 1.2f,	VF_CHEAT, "Vertex drag coefficient when blending morph targets" );
	REGISTER_CVAR(ca_lipsync_phoneme_strength, 1.0f, 0, "LipSync phoneme strength" );
	REGISTER_CVAR(ca_AttachmentCullingRation, 200.0f,	0,	"ration between size of attachment and distance to camera" );
	REGISTER_CVAR(ca_travelSpeedScaleMin, 0.5f,	VF_CHEAT,	"Minimum motion travel speed scale (default 0.5)." );
	REGISTER_CVAR(ca_travelSpeedScaleMax, 2.0f,	VF_CHEAT,	"Maximum motion travel speed scale (default 2.0)." );
	REGISTER_CVAR(ca_AMC_TurnLeaning, 0.35f,	0,	"lean stronger in curves" );
	REGISTER_CVAR(ca_cloth_max_timestep, 0.0f, 0,	"" );
	REGISTER_CVAR(ca_cloth_max_safe_step, 0.0f, 0,	"if a segment stretches more than this (in *relative* units), its length is reinforced" );
	REGISTER_CVAR(ca_cloth_stiffness, 0.0f, 0,	"stiffness for stretching" );
	REGISTER_CVAR(ca_cloth_thickness, 0.0f, 0,	"thickness for collision checks" );
	REGISTER_CVAR(ca_cloth_friction, 0.0f, 0,	"" );
	REGISTER_CVAR(ca_cloth_stiffness_norm, 0.0f, 0,	"stiffness for shape preservation along normals (\"convexity preservation\")" );
	REGISTER_CVAR(ca_cloth_stiffness_tang, 0.0f, 0,	"stiffness for shape preservation against tilting" );
	REGISTER_CVAR(ca_cloth_damping, 0.0f, 0,	"" );
	REGISTER_CVAR(ca_cloth_air_resistance, 0.0f, 0,	"\"advanced\" (more correct) version of damping" );
	
	REGISTER_CVAR(ca_MotionBlurMovementThreshold, 0.001f, 0,	"\"advanced\" Set motion blur movement threshold for discarding skinned object" );




#define FACIAL_ANIM_RAD_DEF 30.f

	REGISTER_CVAR(ca_FacialAnimationRadius, FACIAL_ANIM_RAD_DEF, VF_CHEAT, "Maximum distance at which facial animations are updated - handles zooming correctly");
#undef FACIAL_ANIM_RAD_DEF

	static ICVar *p_e_lod_ratio = g_pISystem->GetIConsole()->GetCVar("ca_lod_ratio");
	float eLod = 6.0f;
	if (p_e_lod_ratio)
		eLod = p_e_lod_ratio->GetFVal();

	REGISTER_CVAR(ca_lod_ratio, eLod,	VF_DUMPTODISK,	"Character LOD ratio" );

}